package com.cuc.platform.core.componet.security.service.logic;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.cuc.platform.core.componet.security.dao.SecurityUserDao;
import com.cuc.platform.core.componet.security.domain.SecurityUser;
import com.cuc.platform.core.componet.security.service.SecurityUserService;
import com.cuc.platform.core.componet.security.utils.Digests;
import com.cuc.platform.core.componet.security.utils.Encodes;
import com.cuc.platform.core.componet.security.utils.SecurityIdentityTools;
import com.cuc.platform.core.service.ServiceException;

/**
 * @author peepul
 * 
 * 系统用户业务实现类
 */
@Service("SecurityUserService")
public class SecurityUserServiceImpl implements SecurityUserService {
	
	@Override
	public SecurityUser getLoginUser(String loginName) {
		if ((null == loginName)|| loginName.equals("")) return null;
		
		return securityUserDao.getUserByLoginName(loginName);
		
	}

	/* (non-Javadoc)
	 * @see com.cuc.platform.core.service.securtity.SecurityUserService#getSecurityUser(java.lang.String)
	 */
	@Override
	public SecurityUser getSecurityUser(Long id) {
		if (null == id) return null;
		
		return securityUserDao.getUserById(id);
	}

	/* (non-Javadoc)
	 * @see com.cuc.platform.core.service.securtity.SecurityUserService#getAllUsers()
	 */
	@Override
	public List<SecurityUser> getAllUsers() {
		return securityUserDao.getAllUsers();
	}
	
	/* (non-Javadoc)
	 * @see com.cuc.platform.core.componet.security.service.SecurityUserService#getUserWithRoles(java.lang.String)
	 */
	@Override
	public List<Map<String, Object>> getUserWithRoles(String userName) {
		if ((null == userName)|| userName.equals("")) return null;
		
		return securityUserDao.getUserWithRoles(userName);
	}

	@Override
	public void insertUser(SecurityUser user) throws ServiceException {
		if (null == user) return;
		
		//设置密码
		this.editEntryptPassword(user);
		
		/* 赋默认值 */
		//用户初始状态，可用
		Integer status = user.getStatus();
		if(null == status){
			user.setStatus(SecurityIdentityTools.IS_ABLE);
		}
		
		//非系统管理级用户
		String isAdmin = user.getIsAdmin();
		if (null == isAdmin || isAdmin.equals("")){
			user.setIsAdmin(SecurityIdentityTools.NO_ADMIN);
		}
		
		securityUserDao.insertUser(user);
	}

	@Override
	public void updateUser(SecurityUser user) throws ServiceException {
		if (null == user || null == user.getId()) return;

		/* 赋默认值 */
		//用户初始状态，可用
		Integer status = user.getStatus();
		if(null == status){
			user.setStatus(SecurityIdentityTools.IS_ABLE);
		}
		
		//非系统管理级用户
		String isAdmin = user.getIsAdmin();
		if (null == isAdmin || isAdmin.equals("")){
			user.setIsAdmin(SecurityIdentityTools.NO_ADMIN);
		}		
		
		securityUserDao.updateUser(user);
	}

	@Override
	public void delUserById(Long id) throws ServiceException {
		if (null == id) return;
		
		try{
			int rv = securityUserDao.delUserById(id);
			
			//如果返回值为0,则没找到对应id的数据，抛出业务异常给web层
			if(rv == 0){
				logger.warn("没找到id为：" + id + "的数据，无效的删除操作。");
				throw new ServiceException("系统中不存在要删除的数据！");
			}
		}catch(DataAccessException ex){
			logger.error("该用户有关联的角色，无效的删除操作。");
			throw new ServiceException("请先删除与角色的关联，才能删除本条数据。");
		}
	}

	@Override
	public List<SecurityUser> findRoleswithUsers(Long userId) {
		if (null == userId) return null;
		
		return securityUserDao.viewRoleswithUsers(userId);
	}

	/* (non-Javadoc)
	 * @see com.cuc.platform.core.componet.security.service.SecurityUserService#saveUserRoleUnions(java.lang.String, java.lang.String[])
	 */
	@Override
	public void saveUserRoleUnions(String user_id, String[] role_ids) {
		if ((null == user_id) || user_id.equals("")) return;
		
		//首先删除该user_id对应的关联关系(除管理级别的)，以避免插入重复数据，然后再循环插入。
		securityUserDao.delUserRoleUnions(Long.valueOf(user_id));
		
		if (null == role_ids) return;

		/*插入多条关联数据。实际批量数据不多，所以没有采用Mybatis的批量插入方式*/
		//构造参数map
		Map<String, Long> map = new HashMap<String, Long>();
		map.put("user_id", Long.valueOf(user_id));
		for(String role_id : role_ids){
			map.put("role_id", Long.valueOf(role_id));
			securityUserDao.saveUserRoleUnions(map);
		}		
	}
	
	/* (non-Javadoc)
	 * @see com.cuc.platform.core.componet.security.service.SecurityUserService#updateUserStatus(com.cuc.platform.core.componet.security.domain.SecurityUser)
	 */
	@Override
	public void updateUserStatus(Long userId, Integer status) throws ServiceException {
		if((null == userId) || (null == status)) return;
		
		//为对象赋值
		SecurityUser user = new SecurityUser();
		user.setId(userId);
		user.setStatus(status);
		
		securityUserDao.updateUserStatus(user);
	}	
	
	/**
	 * private contents 
	 */
	
	/**
	 * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
	 */
	public SecurityUser editEntryptPassword(SecurityUser user) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		user.setSalt(Encodes.encodeHex(salt));

		byte[] hashPassword = Digests.sha1(user.getPlainPassword().getBytes(), salt, HASH_INTERATIONS);
		user.setPassword(Encodes.encodeHex(hashPassword));
		
		return user;
	}
	
	//日志
	private static Logger logger = Logger.getLogger(SecurityResourceServiceImpl.class);
	
	/****************************************************
	 * Setter methods for dependency injection								
	 ****************************************************/
	@Resource
	private SecurityUserDao securityUserDao;

	public void setSecurityUserDao(SecurityUserDao securityUserDao) {
		this.securityUserDao = securityUserDao;
	}
}
